package com.cloudkinto.service.order.box.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.bo.order.inbound.InputBoxTypeQueryBo;
import com.cloudkinto.bo.order.inbound.TransferReceiptConfirmBo;
import com.cloudkinto.bo.order.inbound.TransferReceiptConfirmDetailBo;
import com.cloudkinto.bo.order.inbound.TransferReceiptConfirmNewProductBo;
import com.cloudkinto.common.BeanConvert;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.dao.OrderBoxDao;
import com.cloudkinto.entity.OrderBoxDo;
import com.cloudkinto.service.order.box.OrderBoxService;
import com.cloudkinto.vo.order.inbound.InputBoxTypeNumberVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 入库单产品箱子 service实现类
 * </p>
 *
 * @author long
 * @since 2024-11-04
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class OrderBoxServiceImpl extends ServiceImpl<OrderBoxDao, OrderBoxDo> implements OrderBoxService {

    @Override
    public void batchInsert(List<OrderBoxDo> boxList) {
        baseMapper.insertBatch(boxList);
    }

    @Override
    public List<OrderBoxDo> transferReceiptConfirmNewProductKeepList(TransferReceiptConfirmBo bo) {
        List<String> boxTypeNumberList = bo.getDetailList().stream()
                .map(TransferReceiptConfirmDetailBo::getBoxTypeNumber)
                .collect(Collectors.toList());
        return baseMapper.transferReceiptConfirmNewProductKeepList(bo.getId(), boxTypeNumberList);
    }

    @Override
    public void transferReceiptConfirmNewProductKeep(List<TransferReceiptConfirmNewProductBo> bo) {
        for (TransferReceiptConfirmNewProductBo newProductBo : bo) {
            this.lambdaUpdate()
                    .eq(OrderBoxDo::getBoxTypeNumber, newProductBo.getBoxTypeNumber())
                    .set(OrderBoxDo::getLength, newProductBo.getWmsLength())
                    .set(OrderBoxDo::getWidth, newProductBo.getWmsWidth())
                    .set(OrderBoxDo::getHeight, newProductBo.getWmsHeight())
                    .set(OrderBoxDo::getWeight, newProductBo.getWmsWeight())
                    .set(OrderBoxDo::getLengthBs, newProductBo.getWmsLengthBs())
                    .set(OrderBoxDo::getWidthBs, newProductBo.getWmsWidthBs())
                    .set(OrderBoxDo::getHeightBs, newProductBo.getWmsHeightBs())
                    .set(OrderBoxDo::getWeightBs, newProductBo.getWmsWeightBs())
                    .update();
        }
    }

    @Override
    public PageResult<InputBoxTypeNumberVo> getBoxTypeNumberListPage(InputBoxTypeQueryBo bo) {
        Integer current = bo.getCurrent();
        Integer pageSize = bo.getPageSize();
        PageHelper.startPage(current, pageSize);
        List<InputBoxTypeNumberVo> list = baseMapper.getBoxTypeNumberListPage(bo);
        PageInfo<InputBoxTypeNumberVo> pageInfo = new PageInfo<>(list);
        return new PageResult<>(
                this.handlerBoxTypeNumberListAfter(list),
                current,
                pageSize,
                (int) pageInfo.getTotal(),
                pageInfo.getPages()
        );
    }


    private List<InputBoxTypeNumberVo> handlerBoxTypeNumberListAfter(List<InputBoxTypeNumberVo> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        List<String> boxTypeNumberList = list.stream().map(InputBoxTypeNumberVo::getBoxTypeNumber).distinct().collect(Collectors.toList());
        if (CollUtil.isNotEmpty(boxTypeNumberList)) {
            Map<String, OrderBoxDo> boxTypeNumberMatchInfo = this.lambdaQuery()
                    .select(OrderBoxDo::getBoxTypeNumber,
                            OrderBoxDo::getCustomizeBarcode,
                            OrderBoxDo::getLength,
                            OrderBoxDo::getLengthBs,
                            OrderBoxDo::getWidth,
                            OrderBoxDo::getWidthBs,
                            OrderBoxDo::getHeight,
                            OrderBoxDo::getHeightBs,
                            OrderBoxDo::getWeight,
                            OrderBoxDo::getWeightBs
                    )
                    .in(OrderBoxDo::getBoxTypeNumber, boxTypeNumberList)
                    .groupBy(OrderBoxDo::getBoxTypeNumber)
                    .list().stream().collect(Collectors.toMap(OrderBoxDo::getBoxTypeNumber, item -> item, (key1, key2) -> key1));
            if (CollUtil.isNotEmpty(boxTypeNumberMatchInfo)) {
                for (InputBoxTypeNumberVo inputBoxTypeNumberVo : list) {
                    OrderBoxDo orderBoxDo = boxTypeNumberMatchInfo.get(inputBoxTypeNumberVo.getBoxTypeNumber());
                    if (Objects.nonNull(orderBoxDo)) {
                        BeanConvert.INSTANCE.orderBoxDoToInputBoxTypeNumberVo(orderBoxDo, inputBoxTypeNumberVo);
                    }
                }
            }
        }
        return list;
    }

}
